/**
 * \file Contour.cpp
 * \author Florian LANCE - Armand POLI
 * \version 1.0
 * \date octobre 2011
 */


#include "Contour.h"
#include <iostream>
#include <fstream>
#include <string>


using namespace std;

/// ########################################################################## CONSTRUCTEUR / DESTRUCTEUR

Contour::Contour(){}

Contour::Contour(vector<Point> _tabPoints)
{
    for(uint i = 0; i < _tabPoints.size(); i++)
    {
        complex<double> c;
        c.real(_tabPoints[i].x());
        c.imag(_tabPoints[i].y());
        sequence.push_back(c);
    }

    if(N%2 != 0) cout << "Nombre de points impair." << endl;
    N = sequence.size();

}

Contour::~Contour(){}

/// ########################################################################## ACCESSEURS

tab_cx Contour::TF() const {return suiteFourier;}

tab_cx Contour::S() const  {return sequence;}

tab_cx Contour::Filtre() const  {return filtre;}

/// ########################################################################## FONCTIONS

void Contour::aff(tab_cx &_tabC)
{
    for(uint i = 0; i < _tabC.size(); i++)
    {
        cout << _tabC[i].real() << " " << _tabC[i].imag() <<"_i | ";
    }
}



tab_cx Contour::calculTF()
{

    suiteFourier.clear();
    for(int m = -N/2; m < N/2; m++)
    {
        complex<double> c(0,0);

        for(int n = 0; n <= N-1; n++)
        {
            cx cExp(std::exp(cx(0,-(2.0*M_PI*m*n)/N)));
            c += sequence[n] * cExp;
        }

        c *= complex<double>(1.f/N,0);

        suiteFourier.push_back(c);
    }
    return suiteFourier;
}


tab_cx Contour::calculInvTF()
{
    tab_cx retour;

    for(int n = 0; n < N; n++)
    {
        cx c(0,0);

        for(int m = -N/2; m <= (N-1)/2; m++)
        {
            cx cExp(std::exp(cx(0,(2.0*M_PI*m*n)/N)));
            c += suiteFourier[m+ N/2] * cExp;
        }
        retour.push_back(c);
    }
    return retour;
}

tab_cx Contour::calculFiltreTF(const int _K)
{
    filtre.clear();

    for(int n = 0; n < N; n++)
    {
        cx c(0,0);

        for(int m = -_K; m <= _K; m++)
        {
            cx cExp(std::exp(cx(0,(2.0*M_PI*m*n)/N)));
            c += suiteFourier[N/2 + m] * cExp;
        }

        if(c.imag() < 0) c.imag(c.imag()*-1);
        if(c.real() < 0) c.real(c.real()*-1);

        filtre.push_back(c);
    }
    return filtre;
}

void Contour::enregistrerContour(const string &_s)
{
    ofstream flux(_s.c_str());
    if(flux)
    {
        for(uint i = 0; i < sequence.size(); i++)
        {
            flux << sequence[i].real() << " " << sequence[i].imag() << endl;
        }

        flux.close();
    }
    else
    {
        cout << "ERREUR: Impossible d'enregistrer le contour "<< _s << "." << endl;
    }
}

void Contour::chargerContour(const string &_s)
{
    sequence.clear();
    suiteFourier.clear();

    ifstream flux(_s.c_str());

    if(flux)
    {
        int real,imag;

        while(flux)
        {
            flux >> real;
            flux >> imag;

            cx c;
            c.real(real);
            c.imag(imag);
            sequence.push_back(c);

        }
        flux.close();

        N = sequence.size();

    }
    else
    {
        cout << "ERREUR: Impossible d'ouvrir le contour "<< _s << "." << endl;
    }
}

